package cn.ezios.huo.code.factory;

import cn.ezios.huo.code.factory.build.ControllerModel;
import cn.ezios.huo.code.factory.build.DTOModel;
import cn.ezios.huo.code.factory.build.MetaInfo;
import cn.ezios.huo.system.dao.domain.*;
import cn.hutool.core.map.MapUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.SneakyThrows;
import org.springframework.core.io.ClassPathResource;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

public class Code {

    private final Configuration cfg = new Configuration(Configuration.VERSION_2_3_32);

    public Code() {
        ClassPathResource template = new ClassPathResource("template");
        try {
            cfg.setDirectoryForTemplateLoading(template.getFile());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static Code create() {
        return new Code();
    }

    public static void main(String[] args) {
        List<Class<? extends Serializable>> classes = List.of(SysDictOption.class, SysDictCatalog.class, SysMenu.class, SysRole.class, SysRoleMenu.class, SysUser.class, SysUserRole.class, SysUserAuthLog.class);
        for (Class<? extends Serializable> clz : classes) {
            t2(clz);
        }
    }


    public static void t1() {
        Code code = new Code();
        boolean b = false;
        if (b) {
            File file = new File("D:\\workspace\\java\\huo-admin-boot\\Huo-Code-Factory\\src\\main\\cava\\cn\\ezios\\huo\\code");
            boolean exists = file.exists();
            if (!exists) {
                file.mkdirs();
            }
            return;
        }

        boolean c = true;
        if (c) {
            String property = System.getProperty("user.dir");
            System.out.println(property);
            return;
        }

        try {
            Template template = code.cfg.getTemplate("dto.ftl");
            DTOModel dtoModel = DTOModel.createDTOModelTest1(SysDictCatalog.class);
            dtoModel.setPackageName("cn.ezios.huo.code.dao");
//            template.process(dtoModel, new PrintWriter(System.out));
            FileWriter fileWriter = new FileWriter(pkgToPath("D:\\workspace\\java\\huo-admin-boot\\Huo-Code-Factory", dtoModel.getPackageName(), dtoModel.getClassName() + "DTO.java"));
            template.process(dtoModel, fileWriter);

        } catch (IOException | TemplateException e) {
            throw new RuntimeException(e);
        }
    }

    @SneakyThrows
    public static void t2(Class<?> clz) {
        Code code = create();
        Template dtoTemplate = code.cfg.getTemplate("dto.ftl");
        Template voTemplate = code.cfg.getTemplate("vo.ftl");
        Template controllerTemplate = code.cfg.getTemplate("controller.ftl");
        Template tsApiTemplate = code.cfg.getTemplate("tsApi.ftl");

        MetaInfo metaInfo = new MetaInfo("dist", "cn.ezios.huo.system");
        DTOModel dtoModel = DTOModel.createDTOModelTest2(clz, metaInfo);
        ControllerModel controllerModel = ControllerModel.createControllerModel(clz, metaInfo);


        String controllerPath = metaInfo.classOutputPath() + "\\controller";
//        String daoPath = metaInfo.getOutPutPath() + "\\dao";
        String voPath = metaInfo.classOutputPath() + "\\dao\\vo";
        String dtoPath = metaInfo.classOutputPath() + "\\dao\\dto";
        String apiPath = metaInfo.staticOutputPath() + "\\api";

        metaInfo.createDir(controllerPath);
//        metaInfo.createDir(daoPath);
        metaInfo.createDir(voPath);
        metaInfo.createDir(dtoPath);
        metaInfo.createDir(apiPath);

        FileWriter dtoWriter = new FileWriter(dtoPath + "\\" + dtoModel.getClassName() + "DTO.java");
        dtoTemplate.process(dtoModel, dtoWriter);
        FileWriter voWriter = new FileWriter(voPath + "\\" + dtoModel.getClassName() + "VO.java");
        voTemplate.process(dtoModel, voWriter);
        FileWriter controllerWriter = new FileWriter(controllerPath + "\\" + dtoModel.getClassName() + "Controller.java");
        controllerTemplate.process(controllerModel, controllerWriter);

        FileWriter tsApiWriter = new FileWriter(apiPath + "\\" + dtoModel.getClassName() + "Api.ts");
        Map<Object, Object> map = MapUtil.builder()
                .put("dto", dtoModel)
                .put("controller", controllerModel).build();
        tsApiTemplate.process(map, tsApiWriter);
    }

    public static String pkgToPath(String root, String pkg, String fileName) {
        return root + "\\src\\main\\java\\" + pkg.replace(".", "\\") + "\\" + fileName;
    }

}
